package middleware

import (
	"ReaderInOutLog/util"
	"net/http"
	"strings"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
)

var JwyKey = []byte(util.JwtKey)

type MyClaims struct {
	Username string `json:"username"`
	jwt.StandardClaims
}

// 生成token
func SetToken(username string) (string, int) {
	expireTime := time.Now().Add(time.Hour * 24)

	SetClaims := MyClaims{
		username,
		jwt.StandardClaims{
			ExpiresAt: expireTime.Unix(),
			Issuer:    "myblog",
		},
	}

	// 使用签名的算法和令牌
	reqClain := jwt.NewWithClaims(jwt.SigningMethodHS256, SetClaims)
	token, err := reqClain.SignedString(JwyKey)
	if err != nil {
		return "", 500
	}
	return token, 200
}

func CheckToken(token string) (*MyClaims, int) {
	setToken, _ := jwt.ParseWithClaims(token, &MyClaims{}, func(token *jwt.Token) (interface{}, error) {
		return JwyKey, nil
	})

	if key, _ := setToken.Claims.(*MyClaims); setToken.Valid {
		return key, 200
	}
	return nil, 500
}

var code int

// jwt中间件
func JwtToken() gin.HandlerFunc {
	return func(c *gin.Context) {
		tokenHeader := c.Request.Header.Get("Authorization")
		//  如果token为空 返回错误
		if tokenHeader == "" {
			code = 500
			c.JSON(http.StatusOK, gin.H{
				"status":  code,
				"message": "请求头中auth为空",
			})
			c.Abort()
			return
		}
		checkToken := strings.SplitN(tokenHeader, " ", 2)
		// token类型有错误
		if len(checkToken) != 2 && checkToken[0] != "Bearer" {
			code = 500
			c.JSON(http.StatusOK, gin.H{
				"status":  code,
				"message": "请求头中auth格式有误",
			})
			c.Abort()
			return
		}

		// 验证token
		key, tCode := CheckToken(checkToken[1])
		if tCode == 500 {
			code = 500
			c.JSON(http.StatusOK, gin.H{
				"status":  code,
				"message": "无效的token",
			})
			c.Abort()
			return
		}

		// 判断时间是否过期
		if time.Now().Unix() > key.ExpiresAt {
			code = 500
			c.JSON(http.StatusOK, gin.H{
				"status":  code,
				"message": "授权已过期",
			})
			c.Abort()
			return
		}
		c.Set("claims", key.Username)
		c.Next()
	}
}
